#include "ktlistviewstyle.h"

#include <QStyleOption>
#include <QPainter>
#include <QListView>

KtListViewStyle::KtListViewStyle(QStyle *style/* = nullptr*/) : QProxyStyle(style)
{
    _leftPadding = 11;
    _pItemHeight = 35;
    _pIsTransparent = false;
}

void KtListViewStyle::drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
    switch(element){
    case PE_Widget:
    {
        return ;
    }
    case QStyle::PE_PanelItemViewItem:
    {
        const QStyleOptionViewItem* vopt = qstyleoption_cast<const QStyleOptionViewItem*>(option); // 将选项转换为视图项选项
        if(vopt) {
            painter->save();
            painter->setRenderHint(QPainter::RenderHint::Antialiasing); // 开启抗锯齿，让边缘更平滑

            QRect itemRect = vopt->rect;
            itemRect.adjust(0, 2, 0, -2);
            QPainterPath path;
            path.addRoundedRect(itemRect, 4, 4);

            QColor selectHoverCor(0x4B, 0x4B, 0x4B, 55);
            QColor selectCor(0xCC, 0xCC, 0xCC, 70);
            QColor hoverCor(0xCC, 0xCC, 0xCC, 70);

            if(vopt->state & State_Selected) {
                // 选中Item
                if(vopt->state & State_MouseOver){
                    // 鼠标悬停
                    painter->fillPath(path, selectHoverCor);
                }
                else{
                    painter->fillPath(path, selectCor);
                }
            }
            else {
                // 未选中Item
                if(vopt->state & State_MouseOver){
                    // 鼠标悬停
                    painter->fillPath(path, hoverCor);
                }
            }

            painter->restore();
        }
        return;
    }
    case QStyle::PE_PanelItemViewRow:
    {
        // Item背景隔行变色
        // 开启隔行变色后才可触发
        if (const QStyleOptionViewItem* vopt = qstyleoption_cast<const QStyleOptionViewItem*>(option))
        {
            if (vopt->features == QStyleOptionViewItem::Alternate)
            {
                painter->save();
                painter->setRenderHint(QPainter::Antialiasing);
                painter->setPen(Qt::NoPen);
                painter->setBrush(QColor(0xEF, 0xEF, 0xEF, 160));
                painter->drawRect(vopt->rect);
                painter->restore();
            }
        }
        return;
    }
    default:
    {
        break;
    }
    }

    QProxyStyle::drawPrimitive(element, option, painter, widget);
}

void KtListViewStyle::drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
    switch (element)
    {
    case QStyle::CE_ShapedFrame:
    {
        // viewport视口外的其他区域背景
        if (_pIsTransparent)
        {
            QColor penCor(0xD6, 0xD6, 0xD6);
            QColor brushCor(0xFF, 0xFF, 0xFF, 160);
            QRect frameRect = option->rect;
            frameRect.adjust(1, 1, -1, -1);
            painter->save();
            painter->setRenderHints(QPainter::Antialiasing);
            painter->setPen(penCor);
            painter->setBrush(brushCor);
            painter->drawRoundedRect(frameRect, 3, 3);
            painter->restore();
        }
        return;
    }
    case QStyle::CE_ItemViewItem:
    {
        if (const QStyleOptionViewItem* vopt = qstyleoption_cast<const QStyleOptionViewItem*>(option))
        {
            // 背景绘制
            this->drawPrimitive(QStyle::PE_PanelItemViewItem, option, painter, widget);

            // 内容绘制
            QRect itemRect = option->rect;
            painter->save();
            painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing);
            const QListView* listView = dynamic_cast<const QListView*>(widget);
            if(!listView) break;
            QListView::ViewMode viewMode = listView->viewMode();
            // QRect checkRect = proxy()->subElementRect(SE_ItemViewItemCheckIndicator, vopt, widget);
            QRect iconRect = proxy()->subElementRect(SE_ItemViewItemDecoration, vopt, widget);
            QRect textRect = proxy()->subElementRect(SE_ItemViewItemText, vopt, widget);
            iconRect.adjust(_leftPadding, 0, 0, 0);
            textRect.adjust(_leftPadding, 0, 0, 0);
            // 图标绘制
            if (!vopt->icon.isNull())
            {
                QIcon::Mode mode = QIcon::Normal;
                if (!(vopt->state.testFlag(QStyle::State_Enabled)))
                {
                    mode = QIcon::Disabled;
                }
                else if (vopt->state.testFlag(QStyle::State_Selected))
                {
                    mode = QIcon::Selected;
                }
                QIcon::State state = vopt->state & QStyle::State_Open ? QIcon::On : QIcon::Off;
                vopt->icon.paint(painter, iconRect, vopt->decorationAlignment, mode, state);
            }
            // 文字绘制
            if (!vopt->text.isEmpty())
            {
                QColor textCor(Qt::black);
                painter->setPen(textCor);
                painter->drawText(textRect, vopt->displayAlignment, vopt->text);
            }
            // 选中特效
            if (vopt->state.testFlag(QStyle::State_Selected) && viewMode == QListView::ListMode)
            {
                QColor selectCor(0x00, 0x67, 0xC0);
                int heightOffset = itemRect.height() / 4;
                painter->setPen(Qt::NoPen);
                painter->setBrush(selectCor);
                painter->drawRoundedRect(QRectF(itemRect.x() + 3, itemRect.y() + heightOffset, 3, itemRect.height() - 2 * heightOffset), 3, 3);
            }
            painter->restore();
        }

        return;
    }
    default:
    {
        break;
    }
    }
    QProxyStyle::drawControl(element, option, painter, widget);
}

QSize KtListViewStyle::sizeFromContents(QStyle::ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const
{
    switch (type)
    {
    case QStyle::CT_ItemViewItem:
    {
        QSize itemSize = QProxyStyle::sizeFromContents(type, option, size, widget);
        const QListView* listView = dynamic_cast<const QListView*>(widget);
        QListView::ViewMode viewMode = listView->viewMode();
        if (viewMode == QListView::ListMode)
        {
            itemSize.setWidth(itemSize.width() + _leftPadding);
        }
        itemSize.setHeight(_pItemHeight);
        return itemSize;
    }
    default:
    {
        break;
    }
    }
    return QProxyStyle::sizeFromContents(type, option, size, widget);
}
